import {createDraw} from './Draw'
import {reactive } from 'vue';
let draw = reactive({})
var value //测得的面积或长度
var sketch //当前绘制的要素
//当用户正在绘制多边形时的提示信息文本
var continuePolygonMsg = '双击测量面积';
//当用户正在绘制线时的提示信息文本
var continueLineMsg = '双击测量长度';
// 帮助提示框对象（The help tooltip element.）
var helpTooltipElement;
// 帮助提示框显示的信息（Overlay to show the help messages.）
var helpTooltip = reactive({});
// 测量工具提示框对象（The measure tooltip element. ）
var measureTooltipElement;
// 测量工具中显示的测量值（Overlay to show the measurement.）
var measureTooltip;
// 测量结果的overlay,便于关闭测量之后的删除操作
var drawElements = reactive([])

class Measure {

  //1,----------------测量长度格式化
   static formatLength(line,map) {
    var length;
    var sphere = new ol.Sphere();
    if (sketch) { //若使用测地学方法测量
        var sourceProj = map.getView().getProjection(); //地图数据源投影坐标系
        length = sphere.getLength(line, { "projection": sourceProj, "radius": 6378137 });
    } else {
        length = Math.round(line.getLength() * 100) / 100; //直接得到线的长度
    }
    var output;
    if (length > 100) {
        output = (Math.round(length / 1000 * 100) / 100) + ' ' + 'km'; //换算成KM单位
    } else {
        output = (Math.round(length * 100) / 100) + ' ' + 'm'; //m为单位
    }
    return output;//返回线的长度
};
     
  // 2,------------------------测量面积格式化
  static formatArea(polygon,map){
    var area;
    var sphere = new ol.Sphere();
    if (sketch) {//若使用测地学方法测量
        var sourceProj = map.getView().getProjection();//地图数据源投影坐标系
        var geom = /** @type {ol.geom.Polygon} */(polygon.clone().transform(sourceProj, 'EPSG:4326')); //将多边形要素坐标系投影为EPSG:4326
        area = Math.abs(sphere.getArea(geom, { "projection": sourceProj, "radius": 6378137 })); //获取面积
    } else {
        area = polygon.getArea();//直接获取多边形的面积
    }
    var output;
    if (area > 10000) {
        output = (Math.round(area / 1000000 * 100) / 100) + ' ' + 'km<sup>2</sup>'; //换算成KM单位
    } else {
        output = (Math.round(area * 100) / 100) + ' ' + 'm<sup>2</sup>';//m为单位
    }
    return output; //返回多边形的面积
  };

 
  // 3,--------------------------创建一个新的帮助提示框（tooltip）
  static createHelpTooltip(map) {
    if (helpTooltipElement) {
        helpTooltipElement.parentNode.removeChild(helpTooltipElement);
    }
    helpTooltipElement = document.createElement('div');
    helpTooltipElement.className = 'tooltip hidden';
    helpTooltip.value = new ol.Overlay({
        element: helpTooltipElement,
        offset: [15, 0],
        positioning: 'center-left'
    });
    map.addOverlay(helpTooltip.value);
  }

  
  // 4,----------------------------创建一个新的测量工具提示框（tooltip）
  static createMeasureTooltip(map) {
    if (measureTooltipElement) {
      measureTooltipElement.parentNode.removeChild(measureTooltipElement);
    }
    measureTooltipElement = document.createElement('div');
    measureTooltipElement.className = 'tooltip tooltip-measure';
    measureTooltip = new ol.Overlay({
        element: measureTooltipElement,
        offset: [0, -15],
        positioning: 'bottom-center'
    });
    map.addOverlay(measureTooltip);
    drawElements.push(measureTooltip)
  }

  // 5,----------------------------开始绘制的回调函数
  static drawstartHandle(evt,map,listener){
    // set sketch
    sketch = evt.feature; //绘制的要素 
    var tooltipCoord = evt.coordinate;// 绘制的坐标
    //绑定change事件，根据绘制几何类型得到测量长度值或面积值，并将其设置到测量工具提示框中显示
    listener = sketch.getGeometry().on('change', function (evt) {
        var geom = evt.target;//绘制几何要素
        var output;
        if (geom instanceof ol.geom.Polygon) {
            // ------------这里使用Measure调用,防止this指向为调用drawstartHandle的方法
            output = Measure.formatArea(geom,map);//面积值
            tooltipCoord = geom.getInteriorPoint().getCoordinates();//坐标
        } else if (geom instanceof ol.geom.LineString) {
            // ------------这里使用Measure调用,防止this指向为调用drawstartHandle的方法
            output = Measure.formatLength(geom,map)//长度值
            tooltipCoord = geom.getLastCoordinate();//坐标
        }
        measureTooltipElement.innerHTML = output;//将测量值设置到测量工具提示框中显示
        measureTooltip.setPosition(tooltipCoord);//设置测量工具提示框的显示位置
    });
  }

  //6,-----------------------------结束绘制的回调函数
  static drawendHandle(evt,map,listener){

    measureTooltipElement.className = 'tooltip tooltip-static'; //设置测量提示框的样式
    measureTooltip.setOffset([0, -7]);
    // unset sketch
    sketch = null; //置空当前绘制的要素对象
    // unset tooltip so that a new one can be created
    measureTooltipElement = null; //置空测量工具提示框对象
    this.createMeasureTooltip(map);//重新创建一个测试工具提示框显示结果
    ol.Observable.unByKey(listener);
  }

  // 7,--------------------------------设置鼠标移动回调函数
  static pointerMoverHandle(evt){
    // evt.dragging判断当前是否正在拖动地图
    if(evt.dragging){
        return
    }
    var helpMsg = '点击开始量取';//当前默认提示信息
    if (sketch) {
        var geom = (sketch.getGeometry());
        if (geom instanceof ol.geom.Polygon) {
            helpMsg = continuePolygonMsg; //绘制多边形时提示相应内容
        } else if (geom instanceof ol.geom.LineString) {
            helpMsg = continueLineMsg; //绘制线时提示相应内容
        }
    }
    helpTooltipElement.innerHTML = helpMsg; //将提示信息设置到对话框中显示
    helpTooltip.value.setPosition(evt.coordinate);//设置帮助提示框的位置
    $(helpTooltipElement).removeClass('hidden');//移除帮助提示框的隐藏样式进行显示
  }

  //8,----------------------------测量长度
  static measureLength(map,source){
    map.removeInteraction(draw.value)
    draw.value = createDraw({
      type:'LineString',
      source
    })
    map.addInteraction(draw.value)

    this.createHelpTooltip(map)
    this.createMeasureTooltip(map)
    
    var listener;
    //绑定交互绘制工具开始绘制的事件
    draw.value.on('drawstart', (evt)=>this.drawstartHandle(evt,map,listener),this);
    //绑定交互绘制工具结束绘制的事件
    draw.value.on('drawend',(evt)=>this.drawendHandle(evt,map,listener), this);
    // 鼠标移动事件
    map.on('pointermove',this.pointerMoverHandle); 

  }

  //9,----------------------------测量面积
  static measureArea(map,source){
    map.removeInteraction(draw.value)
    draw.value = createDraw({
      type:'Polygon',
      source
    })
    map.addInteraction(draw.value)

    this.createHelpTooltip(map)
    this.createMeasureTooltip(map)

    var listener;
    //绑定交互绘制工具开始绘制的事件
    draw.value.on('drawstart', (evt)=>this.drawstartHandle(evt,map,listener), this);
    //绑定交互绘制工具结束绘制的事件
    draw.value.on('drawend',(evt)=>this.drawendHandle(evt,map,listener),this);
    // 鼠标移动事件
    map.on('pointermove',this.pointerMoverHandle);   

  }

  // 10,----------------------------------关闭测量
  static closeMeasure(map,source){
    // 移除画笔
    const d = map.removeInteraction(draw.value)
    // map.getInteractions().pop()
    // 清空source
    source.clear()
    // 移除鼠标移动事件
    map.un('pointermove',this.pointerMoverHandle)
    // 移除之前存放长度和距离的图层
    for (let i = 0; i < drawElements.length; i++) {
        map.removeOverlay( drawElements[i])
    }
    // 移除测量工具提示框图层
    map.removeOverlay(helpTooltip.value);
  }
}

export default Measure